package de.core.gameplay.actor.misc;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;


public final class FPSLabel extends Label {

    private long lastTimeRendered = System.currentTimeMillis();
    private int highestFPS;
    private int lowestFPS;
    private final int[] avrgFPS = new int[100];
    private int currentAvrgFPSIndex = 0;


    public FPSLabel(int aX, int aY) {
        this(new Font("Tahoma", Font.BOLD, 11), new Color(255, 255, 255), aX, aY);
    }

    public FPSLabel(Font aFont, int aX, int aY) {
        this(aFont, new Color(255, 255, 255), aX, aY);
    }

    public FPSLabel(Color aColor, int aX, int aY) {
        this(new Font("Tahoma", Font.BOLD, 11), aColor, aX, aY);
    }

    public FPSLabel(Font aFont, Color aColor, int aX, int aY) {
        super("", aFont, aColor, aX, aY);
    }

    @Override
    public void setText(String aText) {
        throw new IllegalStateException("This method should not be called on this class!");
    }

    @Override
    public void setFont(Font aFont) {
        throw new IllegalStateException("This method should not be called on this class!");
    }

    @Override
    public void setColor(Color aColor) {
        throw new IllegalStateException("This method should not be called on this class!");
    }

    @Override
    public void render(Graphics2D aRenderGraphics, float aInterpolation) {
        lastTimeRendered = System.currentTimeMillis();
        super.render(aRenderGraphics, aInterpolation);
    }

    @Override
    protected void act() {
        int fps = calculateFPS();
        highestFPS = fps > highestFPS ? fps : highestFPS;
        lowestFPS = lowestFPS == 0 ? fps : lowestFPS;
        lowestFPS = fps < lowestFPS ? fps : lowestFPS;
        avrgFPS[currentAvrgFPSIndex] = fps;
        currentAvrgFPSIndex++;
        if (currentAvrgFPSIndex >= avrgFPS.length) {
            currentAvrgFPSIndex = 0;
        }

        super.setText("Actors in World: " + getLevel().getActors().size()
                    + " | FPS: " + fps + "(avrg: " + calculateAvrgFPS() + " | max: " + highestFPS
                    + " | min:" + lowestFPS + ")");
    }

    private int calculateFPS() {
        return (int) (1000 / (System.currentTimeMillis() - lastTimeRendered + 1));
    }

    private int calculateAvrgFPS() {
        int result = 0;
        for(int fps : avrgFPS) {
            result += fps;
        }
        return result / avrgFPS.length;
    }
}
